package com.jsu.clubmanagementsystem.service.activity.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsu.clubmanagementsystem.common.ErrorCode;
import com.jsu.clubmanagementsystem.common.PageQueryRequest;
import com.jsu.clubmanagementsystem.constant.UserConstant;
import com.jsu.clubmanagementsystem.exception.BusinessException;
import com.jsu.clubmanagementsystem.mapper.ClubMapper;
import com.jsu.clubmanagementsystem.model.dto.activity.ActivityQueryRequest;
import com.jsu.clubmanagementsystem.model.dto.activitymembership.ActivityMembershipQueryRequest;
import com.jsu.clubmanagementsystem.model.entity.Activity;
import com.jsu.clubmanagementsystem.mapper.ActivityMapper;
import com.jsu.clubmanagementsystem.model.entity.ActivityMembership;
import com.jsu.clubmanagementsystem.model.entity.Club;
import com.jsu.clubmanagementsystem.model.entity.User;
import com.jsu.clubmanagementsystem.model.enums.ActivityStatusEnum;
import com.jsu.clubmanagementsystem.model.vo.activity.ActivityVO;
import com.jsu.clubmanagementsystem.model.vo.club.ClubVO;
import com.jsu.clubmanagementsystem.model.vo.activity.ListActivityVO;
import com.jsu.clubmanagementsystem.model.vo.user.UserVO;
import com.jsu.clubmanagementsystem.service.activity.ActivityMembershipService;
import com.jsu.clubmanagementsystem.service.activity.ActivityService;
import com.jsu.clubmanagementsystem.service.club.ClubMembershipService;
import com.jsu.clubmanagementsystem.service.club.ClubService;
import com.jsu.clubmanagementsystem.service.user.UserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 24753
 * @description 针对表【activity(社团活动)】的数据库操作Service实现
 * @createDate 2025-05-13 17:19:17
 */
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity>
        implements ActivityService {

    @Resource
    private ClubService clubService;

    @Resource
    private UserService userService;

    @Resource
    private ClubMembershipService clubMembershipService;

    @Resource
    private ActivityMembershipService membershipService;

    @Resource
    @Lazy
    private ActivityScheduler activityScheduler;

    @Resource
    @Lazy
    private ClubMapper clubMapper;

    /**
     * 增加活动
     * @param activity
     * @return
     */
    @Override
    public long addActivity(Activity activity) {
        Long clubId = activity.getClubId();
        Club club = clubService.getById(clubId);
        if (club == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "活动所属社团不存在");
        }
        activityValidation(activity, true);

        // 设置初始状态
        if (activity.getStatus() == null) {
            activity.setStatus(ActivityStatusEnum.READY.getCode()); // 默认为确定举办状态
        }
        // 插入数据
        if (!this.save(activity)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加失败");
        }

        //自动添加社长为活动参与者
        ActivityMembership membership = new ActivityMembership();
        membership.setUserId(club.getUserId());
        membership.setActivityId(activity.getId());
        if (!addMemberToActivity(membership)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加社长为活动成员失败");
        }

        //活动被创建，加入修改活动状态任务
        activityScheduler.processUpdateActivity(this.getById(activity.getId()));
        return activity.getId();
    }

    /**
     * 取消活动
     *
     * @param activity
     * @return
     */
    public boolean deleteActivity(Activity activity) {
        //删除所有membership
        Long activityId = activity.getId();
        QueryWrapper<ActivityMembership> activityMembershipQueryWrapper = membershipService.getQueryWrapper(0L, activityId);
        if (!membershipService.remove(activityMembershipQueryWrapper)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除活动成员失败");
        }

        //修改活动状态为已取消
        Activity updatedActivity = new Activity();
        updatedActivity.setId(activityId);
        updatedActivity.setStatus(ActivityStatusEnum.CANCEL.getCode());
        if (!this.updateById(updatedActivity)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新活动状态失败");
        }

        //活动被取消，加入修改活动状态任务
        activityScheduler.processUpdateActivity(this.getById(activity.getId()));
        return true;
    }

    /**
     * 更新活动
     *
     * @param activity
     * @return
     */
    @Override
    public boolean updateActivity(Activity activity) {
        Long activityId = activity.getId();
        Activity existActivity = this.getById(activityId);
        if (existActivity == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "活动不存在");
        }
        if (existActivity.getStatus().equals(ActivityStatusEnum.START.getCode())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "活动已开始，无法修改信息");
        } else if (existActivity.getStatus().equals(ActivityStatusEnum.END.getCode())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "活动已结束，无法修改信息");
        }

        if (activity.getStartTime() == null){
            activity.setStartTime(existActivity.getStartTime());
        }
        if (activity.getEndTime() == null){
            activity.setEndTime(existActivity.getEndTime());
        }
        activityValidation(activity, false);

        if (!this.updateById(activity)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "修改活动信息失败");
        }

        //活动被创建，加入修改活动状态任务
        activityScheduler.processUpdateActivity(this.getById(activity.getId()));
        return true;
    }

    /**
     * 添加成员到活动
     *
     * @param membership
     * @return
     */
    @Override
    public boolean addMemberToActivity(ActivityMembership membership) {
        this.updateActivityMemberValidation(membership, true);
        return membershipService.save(membership);
    }

    /**
     * 从活动中移除成员
     *
     * @param membership
     * @return
     */
    @Override
    public boolean deleteMemberFromActivity(ActivityMembership membership) {
        this.updateActivityMemberValidation(membership, false);
        QueryWrapper<ActivityMembership> queryWrapper = membershipService.getQueryWrapper(membership.getUserId(),
                membership.getActivityId());
        ActivityMembership existMembership = membershipService.getOne(queryWrapper);
        return membershipService.removeById(existMembership);
    }

    /**
     * 获取封装对象
     *
     * @param activity
     * @return
     */
    @Override
    public ActivityVO getActivityVO(Activity activity) {
        if (activity == null) {
            return null;
        }

        ActivityVO activityVO = ActivityVO.objToVo(activity);
        Long clubId = activity.getClubId();
        if (clubId != null && clubId > 0) {
            Club club = clubService.getById(clubId);
            if (club != null) {
                ClubVO clubVO = clubService.getClubVO(club);
                activityVO.setClubVO(clubVO);
            }
        }
        return activityVO;
    }

    /**
     * 获取封装对象 (分页)
     *
     * @param page
     * @return
     */
    @Override
    public Page<ActivityVO> getActivityVoPage(Page<Activity> page) {
        List<Activity> activityList = page.getRecords();
        Page<ActivityVO> activityVOPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        //判空，为空返回空页
        if (CollUtil.isEmpty(activityList)) {
            return activityVOPage;
        }
        //处理封装
        List<ActivityVO> activityVOList = activityList.stream()
                .map(activity -> getActivityVO(activity))
                .collect(Collectors.toList());
        activityVOPage.setRecords(activityVOList);
        return activityVOPage;
    }

    /**
     * 查看活动成员表
     *
     * @param queryRequest
     * @return
     */
    @Override
    public Page<UserVO> listUserVoInActivityByPage(ActivityMembershipQueryRequest queryRequest) {
        Long activityId = queryRequest.getActivityId();
        int current = queryRequest.getCurrent();
        int pageSize = queryRequest.getPageSize();
        QueryWrapper<ActivityMembership> queryWrapper = membershipService.getQueryWrapper(0L, activityId);

        List<User> userList = membershipService.list(queryWrapper).stream()
                .map(activityMembership -> {return userService.getById(activityMembership.getUserId());})
                .collect(Collectors.toList());

        List<UserVO> userVOList = userList.stream()
                .map(user1 -> {return UserVO.objToVoAllInfo(user1);})
                .toList();
        Page<UserVO> page = new Page<>(current, pageSize);
        page.setRecords(userVOList);
        return page;
    }

    /**
     * 查看用户参加过的活动
     * @param queryRequest
     * @return
     */
    @Override
    public Page<ActivityVO> listActivityVoOfUserByPage(ActivityMembershipQueryRequest queryRequest) {
        Long userId = queryRequest.getUserId();
        Long activityId = queryRequest.getActivityId();
        int current = queryRequest.getCurrent();
        int pageSize = queryRequest.getPageSize();
        List<Activity> activityList = this.getActivityListOfUser(userId, activityId);
        List<ActivityVO> activityVOList = activityList.stream().map(this::getActivityVO).toList();
        Page<ActivityVO> activityVOPage = new Page<>(current, pageSize);
        activityVOPage.setRecords(activityVOList);
        return activityVOPage;
    }

    /**
     * 获得查询封装
     *
     * @param queryRequest
     * @return
     */
    @Override
    public QueryWrapper<Activity> getQueryWrapper(ActivityQueryRequest queryRequest) {
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();

        Long id = queryRequest.getId();
        Long clubId = queryRequest.getClubId();
        String activityName = queryRequest.getActivityName();
        String activityTitle = queryRequest.getActivityTitle();
        Integer status = queryRequest.getStatus();
        Date startTime = queryRequest.getStartTime();

        queryWrapper.like(StringUtils.isNotBlank(activityName), "activityName", activityName);
        queryWrapper.like(StringUtils.isNotBlank(activityTitle), "activityTitle", activityTitle);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(clubId), "clubId", clubId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(status), "status", status);
        queryWrapper.ge(ObjectUtils.isNotEmpty(startTime), "startTime", startTime);  // 开始时间在查询条件之后的
        queryWrapper.orderByDesc("startTime");  // 默认按创建时间降序排序
        return queryWrapper;
    }

    /**
     * 获取目标社团的活动列表
     *
     * @param clubId
     * @return
     */
    @Override
    public List<Activity> getActivityListOfClub(Long clubId) {
        ActivityQueryRequest queryRequest = new ActivityQueryRequest();
        queryRequest.setClubId(clubId);
        QueryWrapper<Activity> queryWrapper = this.getQueryWrapper(queryRequest);
        return this.list(queryWrapper);
    }

    /**
     * 获取目标用户参加的活动
     * @param userId
     * @return
     */
    @Override
    public List<Activity> getActivityListOfUser(Long userId, Long activityId){
        QueryWrapper<ActivityMembership> queryWrapper = membershipService.getQueryWrapper(userId, 0L);
        if (activityId != null && activityId != 0L){
            queryWrapper.eq("activityId", activityId);
        }
        List<Activity> activityList = membershipService.list(queryWrapper).stream()
                .map(activityMembership -> {return this.getById(activityMembership.getActivityId());})
                .collect(Collectors.toList());
        return activityList;
    }

    /**
     * 活动是否存在
     *
     * @param activityId
     * @return
     */
    public boolean isExist(Long activityId) {
        if (activityId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        return this.getById(activityId) != null;
    }

    /**
     * 集合中的活动是否都已结束
     *
     * @param activityList
     * @return
     */
    public boolean isActivitiesAllEnd(List<Activity> activityList) {
        if (!activityList.isEmpty())
            for (Activity activity : activityList) {
                if (!activity.getStatus().equals(ActivityStatusEnum.END.getCode()))   // 3-已结束
                    return false;
            }
        return true;
    }

    /**
     * 验证参数
     *
     * @param activity
     */
    @Override
    public void activityValidation(Activity activity, boolean isAdd) {
        if (activity == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }

        String activityName = activity.getActivityName();
        String activityTitle = activity.getActivityTitle();
        String activityContent = activity.getActivityContent();
        Date startTime = activity.getStartTime();
        Date endTime = activity.getEndTime();
        Date nowTime = new Date();

        if (isAdd && StringUtils.isAnyBlank(activityName, activityTitle, activityContent)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "活动名称、标题或内容为空");
        }
        if (isAdd && (startTime == null || endTime == null)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "活动时间不能为空");
        }
        if (ObjectUtils.isNotEmpty(startTime) && startTime.before(nowTime)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "开始时间不能早于当前时间");
        }
        if (ObjectUtils.isNotEmpty(endTime) && endTime.before(startTime)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "结束时间不能早于开始时间");
        }

        if (StringUtils.isNotBlank(activityName) && activityName.length() > 256) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "活动名称过长");
        }
        if (StringUtils.isNotBlank(activityTitle) && activityTitle.length() > 256) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "活动标题过长");
        }
        if (StringUtils.isNotBlank(activityContent) && activityContent.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "活动内容过长");
        }
    }


    /**
     * 修改活动成员的安全验证
     *
     * @param membership
     */
    @Override
    public void updateActivityMemberValidation(ActivityMembership membership, boolean isAddMember) {
        Long userId = membership.getUserId();
        Long activityId = membership.getActivityId();
        if (userId == null || activityId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "用户不存在");
        }
        Activity activity = this.getById(activityId);
        if (activity == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "活动不存在");
        }

        String operation = isAddMember ? "加入" : "退出";
        if (activity.getStatus().equals(ActivityStatusEnum.START.getCode())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "活动已开始，无法" + operation);
        } else if (activity.getStatus().equals(ActivityStatusEnum.END.getCode())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "活动已结束，无法" + operation);
        } else if (activity.getStatus().equals(ActivityStatusEnum.WAITING_REVIEW.getCode())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "活动没有确定举办");
        }

        QueryWrapper<ActivityMembership> queryWrapper = membershipService.getQueryWrapper(userId, activityId);
        boolean isAdded = membershipService.count(queryWrapper) > 0;
        if (isAddMember && isAdded) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户已参与活动");

        } else if (!isAddMember && !isAdded) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "用户没有参加此活动");
        }

        if (isAddMember) {
            if (!clubMembershipService.isMemberOfClub(userId, activity.getClubId())) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户未加入活动所属社团");
            }
        } else {
            if (user.getUserRole().equals(UserConstant.USER_ROLE_MANAGER) && user.getManagedClubId().equals(activity.getClubId())) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户为该活动所属社团社长，无法退出");
            }
        }
    }

    @Override
    public Page<ListActivityVO> getAllActivity(PageQueryRequest page) {
        String query=page.getQuery();
        Page< Activity> iPage =new Page<>( page.getCurrent(), page.getPageSize());
        LambdaQueryWrapper<Activity> activityLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(query!=null){
            activityLambdaQueryWrapper.like(Activity::getActivityName,query).or().like(Activity::getId,query);
        }
        List<Activity> activities = this.baseMapper.getActivity(iPage,activityLambdaQueryWrapper);
        List<ListActivityVO> listActivityVOS = convertActivity(activities);
        Page<ListActivityVO> listActivityVOPage =new Page<ListActivityVO>();
        return listActivityVOPage.setRecords(listActivityVOS).setSize( page.getPageSize()).setCurrent( page.getCurrent()).setTotal(iPage.getTotal());
    }

    @Override
    @Transactional
    public boolean deleteActivitys(List<Long> ids) {
        ids.forEach(id->{
            if(!this.removeById(id)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除失败");
            }
            //同步删除用户与活动的关系
            QueryWrapper<ActivityMembership> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("activityId",id);
            membershipService.getBaseMapper().delete(queryWrapper);
        });
        return true;
    }

    /**
     * 转换List<Activity>->List<ListActivityVO>
     * @param activities
     * @return
     */
    private List<ListActivityVO> convertActivity(List<Activity> activities){
        return activities.stream().map(
                activity -> {
                    ListActivityVO listActivityVO = new ListActivityVO();
                    listActivityVO.setActivityName(activity.getActivityName());
                    listActivityVO.setId(activity.getId());
                    listActivityVO.setClubId(activity.getClubId());
                    listActivityVO.setActivityName(activity.getActivityName());
                    listActivityVO.setActivityTitle(activity.getActivityTitle());
                    listActivityVO.setActivityContent(activity.getActivityContent());
                    listActivityVO.setStartTime(activity.getStartTime());
                    listActivityVO.setEndTime(activity.getEndTime());
                    listActivityVO.setCreateTime(activity.getCreateTime());
                    listActivityVO.setUpdateTime(activity.getUpdateTime());
                    listActivityVO.setStatus(activity.getStatus());
                    listActivityVO.setIsDelete(activity.getIsDelete());
                    listActivityVO.setClubName(clubMapper.getClubName(activity.getClubId()));
                    return listActivityVO;
                }
        ).toList();
    }
}





